﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;

namespace FIS.iDET
{
    public partial class FormMergeTool : Form
    {
        List<ExcelSheet> listExcelSheets1 = null;
        List<ExcelSheet> listExcelSheets2 = null;
        public static List<ExcelSheet> listExcelSheetsResult = null;

        ExcelService excelFile1 = null;
        ExcelService excelFile2 = null;
        ExcelService excelFileSave = null;

        public static PageCompareInfo pageAll = new PageCompareInfo();
        public static List<PageCompareInfo> listPagesCompare = new List<PageCompareInfo>();
        public static List<PageCompareInfo> listAllPagesCompare = new List<PageCompareInfo>();
        List<DataColumn> columns = new List<DataColumn>();

        // string charsRemove = "/ ,.'`";

        int numSheets = 0;
        
        public FormMergeTool()
        {
            InitializeComponent();
        }

        private void buttonExcel1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Excel files|*.xls|All files|*.*";
            openFileDialog.Title = "Open Excel File 1";
            DialogResult result = openFileDialog.ShowDialog();
            if (result == DialogResult.OK && !String.IsNullOrEmpty(openFileDialog.FileName))
            {
                textBoxExcel1.Text = openFileDialog.FileName;
            }
        }
        
        private void buttonExcel2_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Excel files|*.xls|All files|*.*";
            openFileDialog.Title = "Open Excel File 1";
            DialogResult result = openFileDialog.ShowDialog();
            if (result == DialogResult.OK && !String.IsNullOrEmpty(openFileDialog.FileName))
            {
                textBoxExcel2.Text = openFileDialog.FileName;
            }
        }

        private void buttonCompare_Click(object sender, EventArgs e)
        {
            // check condition of all text box to make sure we can run compare
            if (textBoxExcel1.Text != "" && textBoxExcel2.Text != "" && textBoxLayoutFile.Text != "" && textBoxSaveToExcel.Text != "" && Int32.TryParse(textBoxFromSheet.Text, out GlobalVariables.startSheet) && Int32.TryParse(textBoxStartPage.Text, out GlobalVariables.startPage))
            {
                // Init ALL 
                if (GlobalVariables.startSheet == 0)
                {
                    GlobalVariables.startSheet = 1;
                    textBoxFromSheet.Text = "1";
                }

                columns = XmlService.ReadPageCompareXML(textBoxLayoutFile.Text, out pageAll, out listPagesCompare);
                if (columns != null)
                {
                    InitListAllPagesCompare();
                }
                else
                {
                    MessageBox.Show("Wrong FISMAPPING file structure ! Please check and try again");
                    return;
                }

                FormPleaseWait formWait = new FormPleaseWait();
                formWait.Show();

                excelFile1 = new ExcelService(textBoxExcel1.Text);
                excelFile2 = new ExcelService(textBoxExcel2.Text);
                excelFileSave = new ExcelService(textBoxSaveToExcel.Text);
                listExcelSheets1 = new List<ExcelSheet>();
                listExcelSheets2 = new List<ExcelSheet>();
                listExcelSheetsResult = new List<ExcelSheet>();

                if (excelFile1.ImportDataFromExcelFileToCompare(out listExcelSheets1))
                {
                    numSheets = excelFile1.sheetsCount;
                    excelFile1.QuitExcelApp();
                    if (GlobalVariables.startSheet.ToString() != textBoxFromSheet.Text.Trim())
                    {
                        textBoxFromSheet.Text = GlobalVariables.startSheet.ToString();
                    }
                }
                else
                {
                    formWait.Close();
                    return;
                }
                
                if (excelFile2.ImportDataFromExcelFileToCompare(out listExcelSheets2))
                {
                    excelFile2.QuitExcelApp();
                }
                else
                {
                    formWait.Close();
                    return;
                }

                
                // Process

                CompareTwoExcelSheetsArray();
                excelFileSave.SaveComapreResultAsOneSheet(listAllPagesCompare, numSheets, ref listExcelSheetsResult);
                excelFileSave.QuitExcelApp();
                formWait.Close();

                // Reduce memory
                excelFile1 = null;
                excelFile2 = null;
                excelFileSave = null;
                listExcelSheets1 = null;
                listExcelSheets2 = null;
                listExcelSheetsResult = null;
                GC.Collect();
                columns = new List<DataColumn>();
                
                MessageBox.Show("Compare finised !!!");
            }
            else
                MessageBox.Show(" You haven't filled all Required fields. Please check and try again.");
        }

        private void buttonLayoutFile_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "FISMAPPING files|*.fismapping|All files|*.*";
            openFileDialog.Title = "Choose FIS template file";
            DialogResult result = openFileDialog.ShowDialog();
            if (result == DialogResult.OK && !String.IsNullOrEmpty(openFileDialog.FileName))
            {
                textBoxLayoutFile.Text = openFileDialog.FileName;                
            }
        }

        string Standardlize(string s)
        {
            for (int i = 0; i < GlobalVariables.charsRemove.Length; i++)
            {
                char[] c = { GlobalVariables.charsRemove[i] };
                string schar = new string(c);
                s = s.Replace(schar, string.Empty);
            }
            
            for (int i = 0; i < s.Length; i++)
            {
                int charcode = (int)s[i];
                
                char[] c = { s[i] };
                string sC = new string(c);
                
                if ((charcode >= 65296) && (charcode <= 65305))    
                {
                    int charCodeRep = charcode - 65248;
                    char cR = (char)charCodeRep;
                    char[] cRA = { cR };
                    string sR = new string(cRA);
                    s = s.Replace(sC, sR);     
                }
            }
            return s;
        }

        string CompareTwoCellsValue(string s1, string s2)
        {
            s1 = s1.Trim();
            s2 = s2.Trim();
            if ((s1 == "") && (s2 == ""))
                return string.Empty;
            
            int num1 = 0, num2 = 0;
            switch (comboBoxOption.SelectedIndex) // Option 1
            {
                case 0:
                    if (Int32.TryParse(s1, out num1) && Int32.TryParse(s2, out num2))
                        if (num1 == num2)
                            return s1; // 2 number same value 
                    break;
                case 1:
                    if (Int32.TryParse(s1, out num1) && Int32.TryParse(s2, out num2))
                        if (num1 == num2)
                            return s1; // 2 number same value 
                        else
                            return s1 + "<>" + s2; //  != value
                    if ((s1.IndexOf('S') < 0) && (s2.IndexOf('S') < 0)) // No 'S' character
                    {
                        if (Int32.TryParse(s1, out num1))
                            return s1;
                        if (Int32.TryParse(s2, out num1))
                            return s2;
                        // ouput number value
                    }
                    break;
            }
            return s1 + "<>" + s2;
            /* if (s1 == s2) return s1;
            int num;
            if (Int32.TryParse(s1, out num) && !Int32.TryParse(s2, out num)) return s1;
            if (Int32.TryParse(s2, out num) && !Int32.TryParse(s1, out num)) return s2;
            return s1 + "<>" + s2; */
        }

        void CompareTwoExcelSheetsArray()
        {
            // reset data
            listExcelSheetsResult.Clear();
            // init 1 based, not zero base 
            // init listExcelSheetResult Array
            for (int i = 0; i <= numSheets; i++)
                listExcelSheetsResult.Add(new ExcelSheet());
            //
            for (int i = GlobalVariables.startSheet; i <= numSheets; i++)
            {
                try  // handle data compare range in excel file out of Fismapping stipulate !
                {
                    int startRow = listAllPagesCompare[i].startRow;
                    int endRow = listAllPagesCompare[i].endRow;

                    for (int j = 0; j < listAllPagesCompare[i].listColumnCompare.Count; j++)
                    {
                        // Identify compare range
                        int col = listAllPagesCompare[i].listColumnCompare[j].column;

                        switch (listAllPagesCompare[i].listColumnCompare[j].mode)
                        {
                            case CompareMode.COMPARE:
                                for (int row = startRow; row <= endRow; row++)
                                {
                                    string s1 = string.Empty;
                                    string s2 = string.Empty;
                                    if (listExcelSheets1[i].value[row, col] != null)
                                        s1 = listExcelSheets1[i].value[row, col].ToString();
                                    if (listExcelSheets2[i].value[row, col] != null)
                                        s2 = listExcelSheets2[i].value[row, col].ToString();
                                    s1 = Standardlize(s1);
                                    s2 = Standardlize(s2);
                                    listExcelSheetsResult[i].value[row - startRow, j] = CompareTwoCellsValue(s1, s2);
                                    //listExcelSheetsResult[i].value[row-startRow, j] = "'"+ listExcelSheetsResult[i].value[row-startRow, j];
                                }
                                break;
                            case CompareMode.DISPLAY:
                                for (int row = startRow; row <= endRow; row++)
                                {
                                    string s = string.Empty;
                                    if (listAllPagesCompare[i].listColumnCompare[j].source == FileSource.FILE1)
                                    {
                                        if (listExcelSheets1[i].value[row, col] != null)
                                            s = listExcelSheets1[i].value[row, col].ToString();
                                    }
                                    else
                                    {
                                        if (listExcelSheets2[i].value[row, col] != null)
                                            s = listExcelSheets2[i].value[row, col].ToString();
                                    }
                                    listExcelSheetsResult[i].value[row - startRow, j] = s;
                                    //listExcelSheetsResult[i].value[row - startRow, j] = "'" + listExcelSheetsResult[i].value[row - startRow, j];
                                }
                                break;
                            // Create an empty column into excel result
                            case CompareMode.NONE: 
                                break;
                        }
                        
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("Data in Excel file is out of range determited by FISMAPPING file.\nPlease check page number: " + i.ToString() +"\nThe compare process will still continue.\n"+ e.Message , "Compare out of range",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                }
                // add page number
                // DANGEROUS CODE HERE !!!
                int colPageNumber = listAllPagesCompare[i].listColumnCompare.Count;
                int rowPageNumberStart = listAllPagesCompare[i].startRow;
                int rowPageNumberEnd = listAllPagesCompare[i].endRow;
                for (int k = rowPageNumberStart; k <= rowPageNumberEnd; k++)
                {
                    listExcelSheetsResult[i].value[k - rowPageNumberStart, colPageNumber] = GlobalVariables.startPage.ToString();
                }
                GlobalVariables.startPage++;
            }
        }

        void InitListAllPagesCompare()
        {
            // clear list
            listAllPagesCompare.Clear();
            // Init
            for (int i = 0; i < GlobalConstants.maxPagesCompare; i++)
            {
                PageCompareInfo page = new PageCompareInfo();
                page.endRow = pageAll.endRow;
                page.startRow = pageAll.startRow;
                page.listColumnCompare = pageAll.listColumnCompare ;
                listAllPagesCompare.Add(page);
            }

            // Compare information for special pages !

            for (int i = 0; i < listPagesCompare.Count; i++)
            {
                int k = listPagesCompare[i].pageID;
                listAllPagesCompare[k] = listPagesCompare[i];
            }
        }

        private void buttonSaveToExcel_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel|*.xls";
            saveFileDialog.Title = "Save as Excel File";
            DialogResult result = saveFileDialog.ShowDialog();

            if (result == DialogResult.OK && !String.IsNullOrEmpty(saveFileDialog.FileName))
            {
                textBoxSaveToExcel.Text = saveFileDialog.FileName;
            }
        }

        private void FormCompareTool_Load(object sender, EventArgs e)
        {
            textBoxFromSheet.Text = GlobalVariables.startSheet.ToString();
            comboBoxOption.SelectedIndex = 0;
            textBoxStartPage.Text = GlobalVariables.startPage.ToString();
        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
